package com.fansl.allround.upms.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fansl.allround.common.core.bean.UserInfo;
import com.fansl.allround.common.core.exception.CheckedException;
import com.fansl.allround.common.core.util.R;
import com.fansl.allround.common.log.annotation.SysLog;
import com.fansl.allround.common.security.annotation.Inner;
import com.fansl.allround.common.security.util.SecurityUtils;
import com.fansl.allround.upms.api.dto.UnbindSocialInfoDTO;
import com.fansl.allround.upms.api.dto.UserDTO;
import com.fansl.allround.upms.api.entity.SysUser;
import com.fansl.allround.upms.service.SysUserService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.List;
import java.util.Optional;

/**
 * @author fansl
 * @Description: 用户表 前端控制器
 * @date 2019/7/12 18:52
 */
@Slf4j
@RestController
@AllArgsConstructor
@RequestMapping("/user")
public class UserController {
    private final SysUserService userService;

    /**
     * 获取当前用户全部信息
     *
     * @return 用户信息
     */
    @GetMapping(value = {"/info"})
    public R info() {
        Integer userId = SecurityUtils.getUser().getId();
        log.info("获取当前用户全部信息,用户ID:{}", userId);
        SysUser user = userService.getOne(Wrappers.<SysUser>query()
                .lambda().eq(SysUser::getUserId, userId));
        return Optional.ofNullable(user)
                .map((sysUser) -> {
                    log.info("获取当前用户全部信息,用户ID:{},查询用户详细信息", userId);
                    return new R(userService.getUserInfo(sysUser));
                }).orElseGet(() -> {
                    log.warn("获取当前用户全部信息,用户ID:{}，获取当前用户信息失败", userId);
                    return new R(Boolean.FALSE, "获取当前用户信息失败");
                });
    }

    /**
     * 获取指定用户全部信息
     *
     * @return 用户信息
     */
    @Inner
    @GetMapping("/info/{username}")
    public UserInfo info(@PathVariable String username) {
        SysUser user = userService.getOne(Wrappers.<SysUser>query()
                .lambda().eq(SysUser::getUsername, username));
        return Optional.ofNullable(user)
                .map((sysUser -> userService.getUserInfo(user)))
                .orElse(null);
    }

    /**
     * 通过ID查询用户信息
     *
     * @param id ID
     * @return 用户信息
     */
    @GetMapping("/{id}")
    public R user(@PathVariable Integer id) {
        return new R<>(userService.getUserVoById(id));
    }

    /**
     * 根据用户名查询用户信息
     *
     * @param username 用户名
     * @return
     */
    @GetMapping("/details/{username}")
    public R user(@PathVariable String username) {
        SysUser condition = new SysUser();
        condition.setUsername(username);
        return new R<>(userService.getOne(new QueryWrapper<>(condition)));
    }

    /**
     * 删除用户信息
     *
     * @param id ID
     * @return R
     */
    @SysLog("删除用户信息")
    @DeleteMapping("/{id}")
    @PreAuthorize("@pms.hasPermission('sys_user_del')")
    public R userDel(@PathVariable Integer id) {
        SysUser sysUser = userService.getById(id);
        return new R<>(userService.removeUserById(sysUser));
    }

    /**
     * 添加用户
     *
     * @param userDto 用户信息
     * @return success/false
     */
    @SysLog("添加用户")
    @PostMapping
    @PreAuthorize("@pms.hasPermission('sys_user_add')")
    public R user(@RequestBody UserDTO userDto) {
        return new R<>(userService.saveUser(userDto));
    }

    /**
     * 更新用户信息
     *
     * @param userDto 用户信息
     * @return R
     */
    @SysLog("更新用户信息")
    @PutMapping
    @PreAuthorize("@pms.hasPermission('sys_user_edit')")
    public R updateUser(@Valid @RequestBody UserDTO userDto) {
        return new R<>(userService.updateUser(userDto));
    }

    /**
     * 分页查询用户
     *
     * @param page    参数集
     * @param userDTO 查询参数列表
     * @return 用户集合
     */
    @GetMapping("/page")
    public R getUserPage(Page page, UserDTO userDTO) {
        return new R<>(userService.getUserWithRolePage(page, userDTO));
    }

    /**
     * 修改个人信息
     *
     * @param userDto userDto
     * @return success/false
     */
    @SysLog("修改个人信息")
    @PutMapping("/edit")
    public R updateUserInfo(@Valid @RequestBody UserDTO userDto) {
        return userService.updateUserInfo(userDto);
    }

    /**
     * @param username 用户名称
     * @return 上级部门用户列表
     */
    @GetMapping("/ancestor/{username}")
    public R listAncestorUsers(@PathVariable String username) {
        return new R<>(userService.listAncestorUsersByUsername(username));
    }

    /**
     * 重置初始密码
     *
     * @param userId
     * @return 重置后的密码
     */
    @SysLog("重置初始密码")
    @PreAuthorize("@pms.hasPermission('sys_password_reset')")
    @PutMapping("/reset/{userId}")
    public R resetPassword(@PathVariable Integer userId) {
        return new R<>(userService.resetInitPassword(userId));
    }

    /**
     * 更新用户角色
     *
     * @param userId
     * @param roleIdList
     * @return true/false
     */
    @SysLog("更新用户角色")
    @PreAuthorize("@pms.hasPermission('sys_user_role_add')")
    @PutMapping("/role/{userId}")
    public R updateUserRole(@PathVariable Integer userId,
                            @RequestBody List<Integer> roleIdList) {
        if (roleIdList.size() == 0) {
            throw new CheckedException("角色ID不能为空");
        }
        return new R<>(userService.updateUserRole(userId, roleIdList));
    }

    /**
     * 绑定用户社交信息
     *
     * @param unbindSocialInfoDTO 解绑的三方信息
     * @return
     */
    @PostMapping("/social/unbind")
    public Boolean unbindSocialInfo(@RequestBody UnbindSocialInfoDTO unbindSocialInfoDTO) {
        return userService.unbindSocialInfo(unbindSocialInfoDTO);
    }
}
